package logic

import (
	"log"
	"msgserver/constant"
	"msgserver/db"
	"msgserver/net"
	"msgserver/server/common"
	"msgserver/server/game/gameConfig"
	"msgserver/server/game/model"
	"msgserver/server/game/model/data"
	"msgserver/utils"
	"time"
)

var RoleService = &roleService{}

type roleService struct{}

func (r *roleService) EnterServer(uid int, rsp *model.EnterServerRsp, req *net.WsMsgReq) error {
	role := &data.Role{}
	session := db.Engine.NewSession()
	defer session.Close()
	if err := session.Begin(); err != nil {
		log.Println("事务开启出错", err)
		return common.New(constant.DBError, "数据库出错")
	}
	req.Context.Set("dbSession", session)
	ok, err := db.Engine.Table(role).Where("uid=?", uid).Get(role) //获取用户对应的角色
	if err != nil {
		log.Println("查询角色出错", err)
		return common.New(constant.DBError, "数据库出错")
	}
	if ok { //查询到角色
		rid := role.RId
		roleRes := &data.RoleRes{}
		ok, err = db.Engine.Table(roleRes).Where("rid=?", rid).Get(roleRes) //查询角色资源
		if err != nil {
			log.Println("查询角色资源出错", err)
			return common.New(constant.DBError, "数据库出错")
		}
		if !ok { // 没有查询到该用户角色对应的资源，该角色没有资源
			// 初始化资源信息,插入到数据库
			roleRes.RId = rid
			roleRes.Gold = gameConfig.Base.Role.Gold
			roleRes.Decree = gameConfig.Base.Role.Decree
			roleRes.Grain = gameConfig.Base.Role.Grain
			roleRes.Iron = gameConfig.Base.Role.Iron
			roleRes.Stone = gameConfig.Base.Role.Stone
			roleRes.Wood = gameConfig.Base.Role.Wood
			_, err := session.Table(roleRes).Insert(roleRes)
			if err != nil {
				log.Println("插入角色资源出错", err)
				return common.New(constant.DBError, "数据库出错")
			}
		}
		//数据库的字段不一定是客户端需要的字段，做业务逻辑的时候 会将数据库的结果 映射到客户端需要的结果上，所以要做一些转换
		rsp.RoleRes = roleRes.ToModel().(model.RoleRes)
		rsp.Role = role.ToModel().(model.Role)
		rsp.Time = time.Now().UnixNano() / 1e6
		rsp.Token, err = utils.Award(rid) //登录游戏时新生成token
		if err != nil {
			log.Println("生成token出错", err)
			return common.New(constant.SessionInvalid, "生成token出错")
		}
		req.Conn.SetProperty("role", role) //在连接中放置属性，在获取角色拥有属性时，需要从连接中获取role的rid
		// 初始化玩家属性
		if err := RoleAttrService.TryCreate(rid, req); err != nil {
			session.Rollback()
			return common.New(constant.DBError, "数据库错误")
		}
		// 初始化玩家城池
		if err := RoleCityService.InitCity(rid, role.NickName, req); err != nil {
			session.Rollback()
			return common.New(constant.DBError, "数据库错误")
		}

	} else { // 未查询到角色
		return common.New(constant.RoleNotExist, "角色不存在")
	}
	err = session.Commit()
	if err != nil {
		log.Println("事务提交出错", err)
		return common.New(constant.DBError, "数据库出错")
	}
	net.Mgr.RoleEnter(req.Conn, role.RId)
	return nil
}

func (r *roleService) GetRoleRes(rid int) (model.RoleRes, error) {
	roleRes := &data.RoleRes{}
	ok, err := db.Engine.Table(roleRes).Where("rid=?", rid).Get(roleRes)
	if err != nil {
		log.Println("查询角色资源出错", err)
		return model.RoleRes{}, common.New(constant.DBError, "数据库出错")
	}
	if ok {
		return roleRes.ToModel().(model.RoleRes), nil
	}
	return model.RoleRes{}, common.New(constant.DBError, "角色资源不存在")
}

func (r *roleService) Get(rid int) *data.Role {
	role := &data.Role{}
	ok, err := db.Engine.Table(role).Where("rid=?", rid).Get(role) //获取用户对应的角色
	if err != nil {
		log.Println("查询角色出错", err)
		return nil
	}
	if ok {
		return role
	}
	return nil
}
